home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / chat / reflect.000 / reflect / 3.0b3 / reflect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  17.5 KB  |  521 lines

  1. /*
  2.  
  3. Copyright 1993, 1994, Cornell University
  4.  
  5. Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose 
  6. and without fee, provided that these copyright and permission notices appear on all copies and 
  7. supporting documentation, the name of Cornell not be used in advertising or publicity pertaining 
  8. to distribution of the program without specific prior permission, notice be given in supporting 
  9. documentation that copying and distribution is by permission of Cornell.  CORNELL MAKES NO 
  10. REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED.  By way of example, but not limitation, 
  11. CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR 
  12. PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, 
  13. TRADEMARKS, OR OTHER RIGHTS.  Cornell shall not be held liable for any liability with respect to 
  14. any claim by the user or any other party arising from use of the program.
  15.  
  16. This material is partially based on work sponsored by the National Science Foundation under Cooperative 
  17. Agreement No. NCR-9318337.  The government has certain rights in this material.
  18.  
  19. */
  20.  
  21. #define __MAIN__
  22.  
  23. #include <stdio.h>
  24. #include <signal.h>
  25. #include <errno.h>
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28.  
  29. #ifndef LINUX
  30. #include <sys/socketvar.h>
  31. #endif
  32.  
  33. #include <sys/time.h>
  34. #include <netinet/in.h>
  35.  
  36. #include "reflect.h"
  37. #include "refmon.h"
  38. #include "globals.h"
  39.  
  40. main(argc, argv)
  41.     int                argc;
  42.     char               *argv[];
  43. {
  44.  
  45.     unsigned char       *msg,*s,*cptr,*cptr1,version;
  46.     VideoPacketHeader   *vidptr, *vtmp; 
  47.     RefConPkt           pkt;
  48.     RefConPkt           *conpkt;
  49.     client              *cltptr,*ctmp;
  50.     vat_client        *mcltptr,*mtmp;
  51.     struct sockaddr_in  csock,clnt_addr;
  52.     struct in_addr      in;
  53.     int                 msglen,type;
  54.     short               datatype; 
  55.     struct timeval      tp;
  56.     struct timezone     tzp;
  57.     char                *tmp;
  58.  
  59.  
  60.     argc--; argv++;
  61.  
  62.     tracefile = LOGFILE;
  63.     maxallowed = DEFMAXCLIENT;
  64.  
  65.     cap = ((1024 * 80) /8);
  66.     cap += (cap * .2);
  67.  
  68.     if (argc > 0)
  69.        load_config(*argv);
  70.     else
  71.        load_config(NULL);
  72.  
  73.     if (strlen(ci_buf) == 0)
  74.        strcpy(ci_buf,CFD);
  75.     
  76.     if (strlen(mp_buf) == 0)
  77.        strcpy(mp_buf,MAX_CL);
  78.  
  79.     if (strlen(dy_buf) == 0)
  80.        strcpy(dy_buf,DENY_ACCESS);
  81.  
  82.     if (strlen(cap_buf) == 0)
  83.        strcpy(cap_buf,CAPMSG);
  84.  
  85.     if (strlen(ml_buf) == 0)
  86.        strcpy(ml_buf,MLMSG);
  87.  
  88.     if (strlen(ms_buf) == 0)
  89.        strcpy(ms_buf,MSMSG);
  90.  
  91.     if (maxsenders == -1)
  92.        maxsenders = maxallowed;
  93.  
  94.     if (maxlurkers == -1) 
  95.        maxlurkers = maxallowed;
  96.  
  97.     if (log_limit != 0)
  98.     {
  99.        if (strcmp(tracefile,"stdout") == 0)
  100.           log_file = stdout;
  101.        else
  102.        {
  103.           if ((log_file = fopen(tracefile,"w")) != NULL)
  104.           {
  105. #ifdef _BSD
  106.              setlinebuf(log_file);
  107. #else
  108.              setvbuf(log_file,NULL,_IOLBF,0);
  109. #endif
  110.              dolog("open_log file: %s\n",tracefile);
  111.           }
  112.           else
  113.              log_limit = 0;
  114.        }
  115.     }
  116.  
  117.     signal(SIGTERM, proc_sig);  
  118.     signal(SIGINT, proc_sig);    
  119.  
  120.     get_my_addr(&myaddr);
  121.     if (myaddr.sin_addr.s_addr == 0)
  122.     {
  123.        dolog("Unable to get a internet address\n");
  124.        exit(1);
  125.     }
  126.  
  127.     init_mem();
  128.     init_socket();
  129.     init_timer();
  130.     open_bcc_servers();
  131.  
  132.     gettimeofday(&tp, &tzp);
  133.     tmp = ctime(&tp.tv_sec);
  134.     tmp[24] = ' ';
  135.     bcopy(tmp,start_time,strlen(tmp));
  136.  
  137.     msg = &buffer[40];
  138.     vidptr = (VideoPacketHeader *) msg;
  139.     while (1)
  140.     {
  141.        type = receive(msg,&msglen,&csock);
  142.        pkts_in++;
  143.        bytes_in += msglen;
  144.  
  145.        if (deny(csock))
  146.        {
  147.           clnt_addr.sin_family = AF_INET;
  148.           clnt_addr.sin_port = htons(VID_PORT);
  149.           bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
  150.           write_msg(&clnt_addr,kMessageType1,dy_buf); 
  151.           continue;
  152.        }
  153.  
  154.        switch (type)
  155.        {
  156.           /* process VAT, MAVEN, and NV packets        */
  157.  
  158.           case VAT_CNTL:
  159.           case MAVEN_CNTL:
  160.           case VAT:
  161.           case MAVEN:
  162.           case NV_UCAST:
  163.           case NV_MCAST:
  164.  
  165.              mbone_pkt(msg,msglen,csock,type);
  166.              break;
  167.  
  168.           case REF1VIDEO:
  169.           case REF2VIDEO:
  170.           case VIDEO:
  171.  
  172. #ifdef DEBUG
  173.              if (debug)
  174.              {
  175.                 if (ntohs(vidptr->message) == kAudio)
  176.                    printf("AUDIO\n");
  177.                 printf("video packet len %d network src %s ", msglen, inet_ntoa(csock.sin_addr));
  178.                 in.s_addr = vidptr->routing.src.addr;
  179.                 printf("content src %s ",inet_ntoa(in));
  180.                 printf("family %d  seq %ld msg %d dtype %d\n", ntohs(vidptr->routing.dest.family),
  181.                             ntohl(vidptr->seqNum), ntohs(vidptr->message),ntohs(vidptr->dataType));
  182.              }
  183. #endif
  184.              /* JAL 5/11 move this check to the very beginning */
  185.  
  186.             if (vidptr->routing.src.addr == 0)
  187.             {
  188.                dolog("received a packet with a 0 source address from %s\n",inet_ntoa(csock.sin_addr));
  189.                break;
  190.             }
  191.  
  192.             if ((cltptr = find_client(csock.sin_addr.s_addr)) == NULL)
  193.             {         
  194. #ifdef DEBUG
  195.                if (debug)
  196.                   printf("client not found \n");
  197. #endif
  198.                if (type == VIDEO)
  199.                {
  200.                   if ((type = get_type(vidptr,csock)) == -1)
  201.                   {
  202.                      dolog("client not found and packet being dropped due to address or configuration restrictions\n");
  203.                      break;
  204.                   }
  205.                }
  206.                else
  207.                   if (type == REF1VIDEO)
  208.                      type = REF1_SERVER;
  209.                   else
  210.                      type = REF2_SERVER;
  211.  
  212.  
  213.                if (ntohs(vidptr->dataType) == kConfigRefType)
  214.                {
  215.                   if ((type != BCC_SERVER) && (type != BCC_CLIENT) && (type != REF3_SERVER) && (type != BCC_GCLIENT))
  216.                   {
  217.                      dolog("Reflector configuration mis-match from %s\n",inet_ntoa(csock.sin_addr));
  218.                      break;
  219.                   }
  220.                }
  221.                else
  222.                   if ((ntohs(vidptr->dataType) != kConfigVideoType) || (ntohs(vidptr->message) != kOpenConnection))
  223.                   {
  224.                      dolog("client not found and initial message is not Open\n");
  225.                      break;
  226.                   }
  227.  
  228.  
  229.                 if ((type == CLIENT) && (conference_id != 0))
  230.                    if ((ntohs(vidptr->conferenceid) != conference_id) && ((conference_id & 0x8000) == 0))
  231.                    {
  232.                       dolog("conference ids do not match %d %d\n",ntohs(vidptr->conferenceid),conference_id);
  233.                       clnt_addr.sin_family = AF_INET;
  234.                       clnt_addr.sin_port = htons(VID_PORT);
  235.                       bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
  236.                       write_msg(&clnt_addr,kMessageType1,ci_buf);
  237.                       break;
  238.                    }
  239.  
  240.                 cptr = (unsigned char *) ((unsigned char *) vidptr + HEADERLEN) + 
  241.                          sizeof(cltptr->clnt_config.clientCount) +
  242.                          sizeof(cltptr->clnt_config.seqNum) +
  243.                          sizeof(cltptr->clnt_config.name) +
  244.                          sizeof(cltptr->clnt_config.sendMode) +
  245.                          sizeof(cltptr->clnt_config.recvMode) +
  246.                          sizeof(cltptr->clnt_config.flags);
  247.  
  248.                 version = *cptr;
  249.  
  250.                 cptr1 = (unsigned char *) ((unsigned char *) vidptr + HEADERLEN) + 
  251.                           sizeof(cltptr->clnt_config.clientCount) +
  252.                           sizeof(cltptr->clnt_config.seqNum) +
  253.                           sizeof(cltptr->clnt_config.name) +
  254.                           sizeof(cltptr->clnt_config.sendMode) +
  255.                           sizeof(cltptr->clnt_config.recvMode);
  256.  
  257.                 /* assume version == 1 is a PC client     */
  258.  
  259.                 if (((*cptr1 & PC_CLIENT) || (version == 1)) && (min_pc_version != 0))
  260.                 {
  261.                    if (version < min_pc_version)
  262.                    {
  263.                       dolog("old PC version # %d is being rejected\n",version);
  264.                       clnt_addr.sin_family = AF_INET;
  265.                       clnt_addr.sin_port = htons(VID_PORT);
  266.                       bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
  267.                       write_msg(&clnt_addr,kMessageType1,mv_pc_buf);
  268.                       break;
  269.                    }
  270.                 }
  271.                 else
  272.                    if (min_mac_version != 0) 
  273.                    {
  274.                       if (version < min_mac_version)
  275.                       {
  276.                          dolog("old MAC version # %d is being rejected\n",version);
  277.                          clnt_addr.sin_family = AF_INET;
  278.                          clnt_addr.sin_port = htons(VID_PORT);
  279.                          bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
  280.                          write_msg(&clnt_addr,kMessageType1,mv_mac_buf);
  281.                          break;
  282.                       }         
  283.                    }
  284.  
  285.                 if ((cltptr = open_connection(vidptr,&csock,type)) != NULL)
  286.                    distribute(vidptr,cltptr,TRUE);
  287.  
  288.                 break;
  289.              }
  290.  
  291. #ifdef DEBUG
  292.              if (debug)
  293.              {
  294.                 if (cltptr->clnt_flags & CLIENT)        
  295.                    printf("CLIENT\n");
  296.  
  297.                 if (cltptr->clnt_flags & BCC_CLIENT)
  298.                    printf("BCC_CLIENT\n");
  299.                 if (cltptr->clnt_flags & BCC_SERVER)  
  300.                    printf("BCC_SERVER\n");
  301.                 if (cltptr->clnt_flags & BCC_ORIGIN)  
  302.                    printf("BCC_ORIGIN\n");
  303.                
  304.                 if (cltptr->clnt_flags & REF1_CLIENT)   
  305.                    printf("REF1_CLIENT\n");
  306.                 if (cltptr->clnt_flags & REF1_SERVER)   
  307.                    printf("REF1_SERVER\n");
  308.                 if (cltptr->clnt_flags & REF1_ORIGIN)   
  309.                    printf("REF1_ORIGIN\n");
  310.                
  311.                 if (cltptr->clnt_flags & REF2_SERVER)  
  312.                    printf("REF2_SERVER\n");
  313.                 if (cltptr->clnt_flags & REF2_ORIGIN)  
  314.                    printf("REF2_ORIGIN\n");
  315.  
  316.                 if (cltptr->clnt_flags & REF3_SERVER)  
  317.                    printf("REF3_SERVER\n");
  318.                 if (cltptr->clnt_flags & REF3_ORIGIN)  
  319.                    printf("REF3_ORIGIN\n");
  320.                 if (cltptr->clnt_flags & BCC_GCLIENT)
  321.                    printf("BCC_GCLIENT\n");
  322.              }
  323. #endif
  324.                
  325. #ifdef DEBUG
  326.              if (debug)
  327.                  printf("client found \n");
  328. #endif
  329.              cltptr->clnt_rtimer = 0;
  330.  
  331.               /* if this is just a keep alive from a REF3 SERVER just return now */ 
  332.               if ((cltptr->clnt_flags & REF3_SERVER) && ((csock.sin_addr.s_addr == vidptr->routing.src.addr)))
  333.                   break;
  334.  
  335.               /* if this is just a keep alive from a BCC SERVER just return now */ 
  336.               if ((cltptr->clnt_flags & BCC_SERVER) && ((csock.sin_addr.s_addr == vidptr->routing.src.addr)))
  337.                   break;
  338.  
  339.               
  340.                switch (ntohs(vidptr->routing.dest.family))
  341.               {
  342.                  case kReflector:
  343.  
  344.                       if ((ntohs(vidptr->dataType) == kConfigVideoType) && 
  345.                            (ntohs(vidptr->message) == kOpenConnection))
  346.                       {
  347.                          /*   added by MAG 6/27/94   */
  348.                          if ((csock.sin_addr.s_addr) == god_ip) 
  349.                          {
  350.                             if (debug)
  351.                                printf("This is the God-ip. Changing conf-id if necessary.\n");
  352.                  
  353.                             if (conference_id != ntohs(vidptr->conferenceid)) 
  354.                             {
  355.                                dolog("Conf-id was %d\n", conference_id);
  356.  
  357.                                conference_id = ntohs(vidptr->conferenceid);
  358.                                cltptr->clnt_conf_id = conference_id;
  359.  
  360.                                dolog("Conf-id changed to %d\n", conference_id);
  361.  
  362.                                /* weed out all the clients who now have bad conf-id's          */
  363.                                /* however if the god-ip changed it to 0, don't kick anybody off*/
  364.  
  365.                                if ((conference_id != 0) && ((conference_id & 0x8000) == 0))
  366.                                   remove_some_clients(conference_id);
  367.                             }
  368.                          }
  369.  
  370.                          continue_connection(cltptr,vidptr);  
  371.                          distribute(vidptr,cltptr,TRUE);
  372.                       }
  373.                       else
  374.                          if ((ntohs(vidptr->dataType) == kConfigVideoType) && 
  375.                               (ntohs(vidptr->message) == kCloseConnection))
  376.                          {
  377.                              if (cltptr->clnt_flags & (BCC_SERVER | REF1_SERVER | REF2_SERVER | REF3_SERVER))
  378.                              {
  379.                                if ((cltptr = find_client(vidptr->routing.src.addr)) == NULL)
  380.                                 {
  381.                                   in.s_addr = vidptr->routing.src.addr;
  382.                                   dolog("Unable to find server's client at %s for close\n",inet_ntoa(in));
  383.                                   break;
  384.                                 }
  385.                              }
  386.  
  387.                              dolog("closing connection from %s\n",cltptr->clnt_config.name);
  388.  
  389.                              if ((cltptr->clnt_flags & HOLD_DOWN) == 0)
  390.                                 hold_down_client(cltptr);
  391.  
  392.                              distribute(vidptr,cltptr,TRUE);
  393.  
  394.                              cltptr->clnt_flags |= HOLD_DOWN;
  395.  
  396.                          }
  397.                     break;
  398.  
  399.                  case kClient:
  400.                       if ((ctmp = find_client(vidptr->routing.dest.addr)) == NULL)
  401.                       {
  402.                          in.s_addr = vidptr->routing.dest.addr;
  403.                          dolog("Unable to find the destination client at %s for a kClient mesg\n",inet_ntoa(in));
  404.                          dolog("msg from %s\n",inet_ntoa(csock.sin_addr));
  405.                          break;
  406.                       }
  407.  
  408.                     if (ntohs(vidptr->message) == kAudio)
  409.                       {
  410.                        if (cltptr->clnt_talker == 0)
  411.                            dolog("%s is speaking privetly to %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  412.  
  413.                         if (cltptr->clnt_talker++ > 50)
  414.                             cltptr->clnt_talker = 0;
  415.                     }
  416.  
  417.                     write_pkt(vidptr,ctmp);
  418.                     break;
  419.  
  420.                  case kGroup:
  421.                      if (cltptr->clnt_flags & (BCC_SERVER | REF1_SERVER | REF2_SERVER | REF3_SERVER))
  422.                       {
  423.                          if ((cltptr = find_client(vidptr->routing.src.addr)) == NULL)
  424.                          {
  425.                             in.s_addr = vidptr->routing.src.addr;
  426.                             dolog("Unable to find server's client at %s for group\n",inet_ntoa(in));
  427.                             break;
  428.                          }
  429.                      }
  430.  
  431.                       datatype = ntohs(vidptr->dataType);
  432.  
  433.                      if (datatype == kAudio)
  434.                         distribute_audio(vidptr,cltptr);
  435.                       else
  436.                          if ((datatype <= kMaxVideoDataType) && (datatype >= kMinVideoDataType))
  437.                          {
  438.                             cltptr->clnt_bytecnt += msglen;
  439.                             distribute(vidptr,cltptr,FALSE);
  440.                          }
  441.                          else
  442.                             if (datatype == kAuxDataTypeData)
  443.                               distribute_aux(vidptr,cltptr);
  444.                              else
  445.                                if (datatype == kAuxDataTypeSupervisor)
  446.                                  distribute(vidptr,cltptr,TRUE);
  447.  
  448.                     break;
  449.  
  450.                    default:
  451.                     dolog("unknown video message type\n");
  452.                     break;
  453.               }
  454.                break;
  455.  
  456.  
  457.            case CONTROL:
  458. #ifdef DEBUG
  459.               if (debug)
  460.                  printf("process control packet\n");
  461. #endif
  462.               conpkt = (RefConPkt *) msg;
  463.  
  464.               if (msglen < MINREFPKT)
  465.               {
  466.                  dolog("msglen is less then MINREFPKT\n");
  467.                  break;    
  468.               }
  469.  
  470.               if (msglen < ntohs(conpkt->msg_len))
  471.               {
  472.                  dolog("conpkt->msg_len is less then msglen\n");
  473.                  break;    
  474.               }
  475.  
  476.               process_control_pkt(conpkt);
  477.  
  478.               break;
  479.  
  480.            default:
  481.               dolog("bad value returned from receive\n");
  482.               exit(1);
  483.        }
  484.  
  485.        if (timer_expired) 
  486.        {
  487.           timer_expired--;
  488.           do_timer();
  489.        }
  490.     }
  491. }
  492.  
  493. init_mem()
  494. {
  495.      unsigned char *stash;
  496.      client *cltptr;
  497.      slist *sptr;
  498.      int cnt;
  499.  
  500.  
  501.  
  502.      if ((stash = (unsigned char *) calloc(MAXCLIENT,sizeof(client))) == NULL)
  503.      {
  504.         dolog("Unable to get client memory\n");
  505.         exit(1);
  506.      }
  507.  
  508.      for (cnt = 0, cltptr = (client *) stash; cnt < MAXCLIENT; cnt++, cltptr++)
  509.          free_client(cltptr);
  510.  
  511.      if ((stash = (unsigned char *) calloc((MAXCLIENT * MAXCLIENT * 3),sizeof(slist))) == NULL)
  512.      {
  513.         dolog("Unable to get slist memory \n");
  514.         exit(1);
  515.      }
  516.  
  517.      for (cnt = 0, sptr = (slist *) stash; cnt < (MAXCLIENT * MAXCLIENT * 3); cnt++, sptr++)
  518.          free_slist(sptr);
  519. }
  520.  
  521.